﻿//#define TEST 
//#define SYNC_READ
using PLC;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using PumpAlgorithm;
using System.Windows.Forms.DataVisualization.Charting;

using Business.Base;
using System.Threading;
using Business.Common;

namespace Pumptester
{
    public partial class MainFrm : Form
    {
        const int    XAxisUnit = 10;
        const int    YAxisUnit = 5;
        const double AxisMaxRate = 0.8f;
        const int    DrawPointCount = 30;
        private Boolean experimentIsRunning = false;
        private bool ExperimentIsRunning { get => experimentIsRunning; set => experimentIsRunning = value; }




        //private IExperimentService experimentSerice;

        #region 组件定义


        private object lockObject = new object();
        private PerfExperiment experiment =null;
        private PerfExperimentRecord currentPerfExperimentRecord =null;
        PLCManager plc = PLCManager.GetInstance();
        ModBusRTUManager modBus = ModBusRTUManager.GetInstance();
        PerfExperimentService service = new PerfExperimentService(); //Xyj后面可以以容器方式创建
        PerfExperimentExcelManager excelManager = new PerfExperimentExcelManager();
        Thread dataGetherThread;
        System.Timers.Timer timer;
        System.Windows.Forms.Timer winTimer = new System.Windows.Forms.Timer();


        #endregion


        public MainFrm()
        {
            InitializeComponent();
#if TEST
            initTestPLCData();
#else
#if SYNC_READ
            dataGetherThread = new Thread(new ThreadStart(GetData));
            dataGetherThread.IsBackground = true;
            dataGetherThread.Start();
#endif
            winTimer.Tick += WinTimer_Tick;
            winTimer.Interval = 1000;
#endif
        }

      

        #region 私有功能函数
        /// <summary>
        /// 状态变化函数
        /// </summary>
        

               

        
        
        /// <summary>
        /// 根据采集的数据，计算出每条记录的值
        /// </summary>
        /// <param name="data">从硬件获取出来的数据</param>
        /// <returns></returns>
        private PerfExperimentRecord caculateExperimentRecord(float presureIn, float presureOut, float flow, float temperature, float speed, float dianya, float dianliu, float yggl,float glys)
        {
            //需要直接和硬件对接时候修改
            PerfExperimentRecord record = new PerfExperimentRecord();


            record.WorkFlow =   flow;
            record.PresureIn =  presureIn;
            record.PresureOut = presureOut;
            record.Voltage =          dianya;
            record.ElectricCurrent =  dianliu;
            record.WorkingPower =     yggl; //需要确认是否对应有功功率
            record.WorkingSpeed = (int)speed==0?3000:speed;//speed; 
            record.Temperature = temperature;
            //确认无功功率,视在功率和功率因子三个是否要记录，对应的其他的变量是什么？





#if TEST
         CanonicalAlgorithm canonicalAlgorithm = new CanonicalAlgorithm(this.zInlet, this.zOutlet, this.kInlet, this.kOutlet, this.dInlet, this.dOutlet, this.lInlet, this.lOutlet, this.efficiency, this.stpRotarySpeed);
#else
            double zInlet = this.experiment.ZInlet;
            double zOutlet = this.experiment.ZOutlet;
            double kInlet = this.experiment.KInlet;
            double kOutlet = this.experiment.KOutlet;
            double lInlet = this.experiment.LInlet;
            double lOutlet = this.experiment.LOutlet;
            double dInlet = this.experiment.DInlet;
            double dOutlet = this.experiment.DOutlet;
            double efficiency = this.experiment.MotorEfficiency;
            double stpRotarySpeed = this.experiment.DesignRatedSpeed;
            CanonicalAlgorithm canonicalAlgorithm = new CanonicalAlgorithm(zInlet, zOutlet, kInlet, kOutlet, dInlet, dOutlet, lInlet, lOutlet, efficiency, stpRotarySpeed);
#endif

            canonicalAlgorithm.setplcEnvData(record);
            //canonicalAlgorithm.setplcEnvData(data.Temperature, data.PresureIn, data.PresureOut, data.Power, data.Flow, (int)data.Speed);

            record.WorkingHead = canonicalAlgorithm.WorkingHead;
            record.StpFlow = canonicalAlgorithm.StpQ;
            record.StpHead = canonicalAlgorithm.StpHead;
            record.StpPowerIn = canonicalAlgorithm.StpPowerIn;
            record.StpShaftPower = canonicalAlgorithm.StpShaftPower;
            record.StpPumpEfficiency = canonicalAlgorithm.StpPumpEfficiency;
            record.StpGroupEfficiency = canonicalAlgorithm.StpGroupEfficiency;
            record.WorkingStaticHead = canonicalAlgorithm.WorkingStaticHead;
            record.WorkingDynamicHead = canonicalAlgorithm.WorkingDynamicHead;
            record.WorkingGeoHead = canonicalAlgorithm.WorkingGeoHead;
            record.WorkingFrictionHead = canonicalAlgorithm.WorkingFrictionHead;
            return record;
        }


        #region 硬件数据采集逻辑,后续需要独立成模块


#if SYNC_READ

        private delegate void ShowMessageDelegate(float presureIn, float presureOut, float flow, float temperature, float speed, float dianya, float dianliu, float yggl,float glys);
        private void ShowData(float presureIn, float presureOut, float flow, float temperature, float speed, float dianya, float dianliu, float yggl, float glys)
        {
            if (this.InvokeRequired)
            {
                ShowMessageDelegate showMessageDelegate = ShowData;
                if (this.IsHandleCreated)
                {
                    this.Invoke(showMessageDelegate, new object[] { presureIn, presureOut, flow, temperature, speed, dianya, dianliu, yggl, glys });
                }
            }
            else
            {
                this.textBoxJKYL.Text = presureIn.ToString();
                this.textBoxCKYL.Text = presureOut.ToString();
                //this.textBoxTHLL.Text = flow.ToString();
                this.textBoxWD.Text =   temperature.ToString();
                this.textBoxDJZS.Text = speed.ToString();
                this.textBoxDL.Text =   dianliu.ToString();
                this.textBoxDY.Text =   dianya.ToString();
                this.textBoxYGGL.Text = yggl.ToString();
                //this.textBoxWGGL.Text = wggl.ToString();
               // this.textBoxSZGL.Text = szgl.ToString();
                this.textBoxGLYS.Text = glys.ToString();

                PerfExperimentRecord record  = caculateExperimentRecord(presureIn, presureOut, flow, temperature, speed, dianya, dianliu, yggl,  glys);
                //赋值
                lock (lockObject)
                {
                    this.currentPerfExperimentRecord = record;
                }

            }
        }


        private void GetData()
        {
            timer = new System.Timers.Timer();
            timer.Interval = 1000;
            timer.Enabled = false;
            timer.AutoReset = true;//设置是执行一次（false）还是一直执行(true)；       
            timer.Elapsed += (o, a) =>
            {
                float presureIn = plc.readVData(100);
                float presureOut = plc.readVData(110);
                float flow = plc.readVData(210); //plc.readVData(experiment.FlowmeterAddress);
                float temperature = plc.readVData(180);
                float speed = plc.readVData(190);  
                ushort[] meanData = modBus.ReadHoldingRegisters(1, 544, 20);
                
                float dianya =   getValue(meanData[0], meanData[1]);
                float dianliu =  getValue(meanData[2], meanData[3])*(float)this.experiment.CurrentTransformationRatio;
                float yggl = getValue(meanData[4], meanData[5])* (float)this.experiment.CurrentTransformationRatio;
                //float wggl = getValue(meanData[6], meanData[7])* (float)this.experiment.CurrentTransformationRatio;//无功功率
                //float szgl = getValue(meanData[8], meanData[9])* (float)this.experiment.CurrentTransformationRatio;//视在功率
                float glys = getValue(meanData[10], meanData[11]);//功率因素
                
                ShowData(presureIn, presureOut, flow, temperature, speed, dianya, dianliu, yggl, glys);
            };
        }
#endif




        #endregion



        #region 测试数据
#if TEST
        int testIndex = 0;
        ArrayList testPLCData;
        
        Double zInlet;
        Double zOutlet;
        Double kInlet;
        Double kOutlet;
        Double dInlet;
        Double dOutlet;
        Double lInlet;
        Double lOutlet;
        Double efficiency;   //标况下的电机效率
        Double stpRotarySpeed;

        void initTestPLCData()
        {
            /*zInlet = 0;              //取压高度
            zOutlet = 80;            //取压高度出口
            kInlet =   0.05;           //进口摩擦系数
            kOutlet =  0.05;          //出口摩擦系数
            dInlet =   80.0f;          //入口直径
            dOutlet =  80.0f;         //出口直径
            lInlet =  2 * dInlet;     //取压空长度,输入口
            lOutlet = 2 * dOutlet;   //去压空长度，输出口
            efficiency = 90.0f;      //标况下的电机效率
            stpRotarySpeed = 1480;   //转速*/

            zInlet = 0;              //取压高度
            zOutlet = 0;            //取压高度出口
            kInlet = 0.05;           //进口摩擦系数
            kOutlet = 0.05;          //出口摩擦系数
            dInlet = 81.0f;          //入口直径
            dOutlet = 81.0f;         //出口直径
            lInlet = 400.0f;     //取压空长度,输入口
            lOutlet = 400.0f;   //去压空长度，输出口
            efficiency = 90.0f;      //标况下的电机效率
            stpRotarySpeed = 4000;   //转速


            Double[,] datas = new Double[,]
            {
                //1.测量的流量值
                //2.输入值进口压力
                //3.输出值出口压力
                //4.电压
                //5.电流
                //6.功率
                //7.转速
                //8.温度
                { 0,          0,   41.63238,    0,   0 ,  1008.888137, 3999.8,  19.870001 },
                {3.612153 ,   0 ,  40.99773,    0,   0  , 1158.143406, 3999   , 20.063147 },
                {7.498365,    0 ,  39.47088,    0 ,  0 ,  1317.43434 , 3999.9 , 19.973012},
                {11.182576,   0 ,  38.78186  ,     0 ,  0  , 1464.996243, 4000.1 , 19.90863},
                {15.031077,   0 ,  37.10966,    0 ,  0 ,  1624.563531, 4000.6 , 19.921507},
                {18.644812,   0 ,  35.38924 ,     0 ,  0 ,  1784.613132, 3999.9 , 19.870001},
                {22.176107 ,  0 ,  36.7993 ,    0 ,  0 ,  1936.297499, 4000.3 , 19.876439},
                {26.116644,   0 ,  34.35272 ,    0 ,  0 ,  2084.386691, 4000.8,  19.812056},
                {29.948536,   0 ,  32.222326 ,    0 ,  0 ,  2242.862603, 3999.5 , 19.676855},
                {33.613707 ,  0 ,  31.89561 ,    0 ,  0 ,  2379.589111, 4000.6,  19.676855},
                {37.286358 ,  0 ,  29.38259 ,    0 ,  0 ,  2485.674208, 4000  ,  19.676855},
                {41.062103 ,  0 ,  28.69765 ,    0 ,  0 ,  2569.233127, 3999.3 , 19.805618},
                {44.696009 ,  0 ,  27.8444 ,    0 ,  0 ,  2615.767117, 4000.3 , 19.831371},
                {48.478684 ,  0 ,  26.94688 ,    0 ,  0 ,  2633.687148, 3999.1 , 19.870001},
                {52.545757 ,  0 ,  25.03125  ,    0 ,  0 ,  2656.621311, 4000.7 , 19.850686},
                {56.050962 ,  0 ,  24.7075 ,     0 ,  0 ,  2629.186984, 3999.4 , 19.824933},
                {59.73587 ,   0 ,  23.08246  ,    0 ,  0 ,  2578.679932, 4000.1 , 19.805618},
                {63.44008,    0 ,  22.0122,   0 ,  0 ,  2538.763183, 4000.2,  19.831371},
                {67.250777 ,  0 ,  19.37631 ,    0 ,  0  , 2465.42825,  3999.7 , 19.870001},
                {70.599366,   0 ,  18.48751 ,    0 ,  0 ,  2336.612169, 3999.7 , 19.805618 },
                {74.167113 ,  0 ,  17.58895 ,    0 ,  0 ,  2242.949938, 4000 ,   19.870001},
                //{78.391573,   0 ,  0.371095 ,    0 ,  0 ,  0 ,  3999.4,  19.870001 },

                /*
                { 17.92,   7.758f,  1.449 ,  24.88,  12.41,    147.07,  2962.48 },
                { 19.42,   7.668,   1.429,   25.67,   12.81,   145.03,  2960.78 },
                { 20.65 ,  7.596  , 1.417 ,  26.27 ,  13.14 ,  143.81 , 2960.91 },
                { 22.01 ,  7.397 ,  1.4,     26.92  , 13.51  , 142.17 , 2958.47 },
                { 22.81 ,  7.614 ,  1.386  , 27.02  , 13.65   ,140.64 , 2957.45 },
                { 23.77 ,  7.234 ,  1.376 ,  27.21 ,  13.71 ,  139.59 , 2956.48 },
                { 24.71 ,  7.252 ,  1.354 ,  27.92 ,  14.08  , 137.48 , 2956.62 },
                { 26.85  , 7.071 ,  1.3,     29.00,   14.74 ,  131.97,  2954.06 },
                { 28.08 ,  6.836 ,  1.273 ,  29.10  , 14.82  , 129.24 , 2954.23 },
                { 29.47 ,  6.908,   1.239  , 30.04 ,  15.36 ,  125.74 , 2952.04 },
                { 30.08 ,  6.691,   1.221 ,  29.70 ,  15.20 ,  123.93 , 2950.41 },
                { 32.12 ,  6.402 ,  1.169  , 30.86 ,  15.71 ,  118.72,  2950.58 },
                { 32.95,   6.33  ,  1.142  , 30.79 ,  15.84  , 115.97,  2949.11 },
                { 34.09 ,  6.167  , 1.116 ,  31.74 ,  16.29 ,  113.31 , 2949.92 },
                { 36.66,   6.058 ,  1.032  , 32.41 ,  16.62 ,  104.74,  2946.01 },
                { 38.30 ,  5.715  , 0.974 ,  32.15 ,  16.62 ,  98.82  , 2946.57 },
                { 39.55,   5.407 ,  0.926 ,  33.30  , 17.21 ,  94.02 ,  2943.73 },
                { 40.86 ,  5.009 ,  0.871 ,  32.79 ,  16.98  , 88.40 ,  2943.40 },
                */
             };
            ArrayList list = new ArrayList();
            for (int i = 0; i < datas.GetLength(0); i++)
            {
                PLCData data = new PLCData();
                data.Flow = datas[i, 0];
                data.PresureIn = datas[i, 1];
                data.PresureOut = datas[i, 2];
                data.ElectricCurrent = datas[i, 3];
                data.Voltage = datas[i, 4];
                data.Power = datas[i, 5];
                data.Speed = datas[i, 6];
                data.Temperature = datas[i, 7];
                list.Add(data);
            }
            testPLCData = list;
        }

        private PerfExperimentRecord caculateExperimentRecord(PLCData data)
        {
            //需要直接和硬件对接时候修改
            PerfExperimentRecord record = new PerfExperimentRecord();


            record.WorkFlow = data.Flow;
            record.PresureIn = data.PresureIn;
            record.PresureOut = data.PresureOut;
            record.Voltage = data.Voltage;
            record.ElectricCurrent = data.ElectricCurrent;
            record.WorkingPower = data.Power;
            record.WorkingSpeed = data.Speed;

            CanonicalAlgorithm canonicalAlgorithm = new CanonicalAlgorithm(zInlet, zOutlet, kInlet, kInlet, dInlet, dOutlet, lInlet, lOutlet, efficiency, stpRotarySpeed);
            canonicalAlgorithm.setplcEnvData(data.Temperature, data.PresureIn, data.PresureOut, data.Power, data.Flow, (int)data.Speed);

            record.WorkingHead = canonicalAlgorithm.WorkingHead;
            record.StpFlow = canonicalAlgorithm.StpQ;
            record.StpHead = canonicalAlgorithm.StpHead;
            record.StpShaftPower = canonicalAlgorithm.StpShaftPower;
            record.StpPumpEfficiency = canonicalAlgorithm.StpPumpEfficiency;
            record.StpGroupEfficiency = canonicalAlgorithm.StpGroupEfficiency;
            record.WorkingStaticHead = canonicalAlgorithm.WorkingStaticHead;
            record.WorkingDynamicHead = canonicalAlgorithm.WorkingDynamicHead;
            record.WorkingGeoHead = canonicalAlgorithm.WorkingGeoHead;
            record.WorkingFrictionHead = canonicalAlgorithm.WorkingFrictionHead;
            return record;
        }

        private void fetchRecordToDataGridView(PLCData data)
        {
            PerfExperimentRecord record = caculateExperimentRecord(data);

            record.RecordTime = DateTime.Now;
            this.experiment.RecordList.Add(record);
            fetchRecordToDataGridViewFromRecord(record);
        }

        private void AddRowDataGridview(PLCData data)
        {
            DataGridViewRow row = (DataGridViewRow)this.dataGridView.RowTemplate.Clone();

            PerfExperimentRecord record = new PerfExperimentRecord();


            DataGridViewTextBoxCell workFlowCell = new DataGridViewTextBoxCell();
            record.WorkFlow = data.Flow;
            workFlowCell.Value = data.Flow.ToString("f6");


            DataGridViewTextBoxCell presureInCell = new DataGridViewTextBoxCell();
            record.PresureIn = data.PresureIn;
            presureInCell.Value = data.PresureIn.ToString("f6");


            DataGridViewTextBoxCell presureOutCell = new DataGridViewTextBoxCell();
            record.PresureOut = data.PresureOut;
            presureOutCell.Value = data.PresureOut.ToString("f6");


            DataGridViewTextBoxCell voltageCell = new DataGridViewTextBoxCell();
            record.Voltage = data.Voltage;
            voltageCell.Value = data.Voltage.ToString("f6");


            DataGridViewTextBoxCell electricCurrentCell = new DataGridViewTextBoxCell();
            record.ElectricCurrent = data.ElectricCurrent;
            electricCurrentCell.Value = data.ElectricCurrent.ToString("f6");


            DataGridViewTextBoxCell powerCell = new DataGridViewTextBoxCell();
            record.WorkingPower = data.Power;
            powerCell.Value = data.Power.ToString("f6");


            DataGridViewTextBoxCell speedCell = new DataGridViewTextBoxCell();
            record.WorkingSpeed = data.Speed;
            speedCell.Value = record.WorkingSpeed.ToString("f6");


            DataGridViewTextBoxCell temperatureCell = new DataGridViewTextBoxCell();
            record.Temperature = data.Temperature;
            temperatureCell.Value = data.Temperature.ToString("f6");


            CanonicalAlgorithm canonicalAlgorithm = new CanonicalAlgorithm(zInlet, zOutlet, kInlet, kInlet, dInlet, dOutlet, lInlet, lOutlet, efficiency, stpRotarySpeed);
            canonicalAlgorithm.setplcEnvData(data.Temperature, data.PresureIn, data.PresureOut, data.Power, data.Flow, (int)data.Speed);

            DataGridViewTextBoxCell workHeadCell = new DataGridViewTextBoxCell();
            record.WorkingHead = canonicalAlgorithm.WorkingHead;
            workHeadCell.Value = record.WorkingHead.ToString("f6");


            DataGridViewTextBoxCell stpQCell = new DataGridViewTextBoxCell();
            record.StpFlow = canonicalAlgorithm.StpQ;
            stpQCell.Value = record.StpFlow.ToString("f6");


            DataGridViewTextBoxCell stpHeadCell = new DataGridViewTextBoxCell();
            record.StpHead = canonicalAlgorithm.StpHead;
            stpHeadCell.Value = record.StpHead.ToString("f6");


            DataGridViewTextBoxCell stpShaftPowerCell = new DataGridViewTextBoxCell();
            record.StpShaftPower = canonicalAlgorithm.StpShaftPower;
            stpShaftPowerCell.Value = record.StpShaftPower.ToString("f6");


            DataGridViewTextBoxCell stpPumpEfficiencyCell = new DataGridViewTextBoxCell();
            record.StpPumpEfficiency = canonicalAlgorithm.StpPumpEfficiency;
            stpPumpEfficiencyCell.Value = record.StpPumpEfficiency.ToString("f6");



            DataGridViewTextBoxCell stpGroupEfficiencyCell = new DataGridViewTextBoxCell();
            record.StpGroupEfficiency = canonicalAlgorithm.StpGroupEfficiency;
            stpGroupEfficiencyCell.Value = record.StpGroupEfficiency.ToString("f6");

            DataGridViewTextBoxCell staticHeadCell = new DataGridViewTextBoxCell();
            //record.StpGroupEfficiency = canonicalAlgorithm.StpGroupEfficiency;

            staticHeadCell.Value = canonicalAlgorithm.WorkingStaticHead.ToString("f6");


            DataGridViewTextBoxCell dynamicHeadHeadCell = new DataGridViewTextBoxCell();
            //record.StpGroupEfficiency = canonicalAlgorithm.StpGroupEfficiency;

            dynamicHeadHeadCell.Value = canonicalAlgorithm.WorkingDynamicHead.ToString("f6");

            DataGridViewTextBoxCell geoHeadHeadCell = new DataGridViewTextBoxCell();
            //record.StpGroupEfficiency = canonicalAlgorithm.StpGroupEfficiency;

            geoHeadHeadCell.Value = canonicalAlgorithm.WorkingGeoHead.ToString("f6");

            DataGridViewTextBoxCell frictionHeadCell = new DataGridViewTextBoxCell();
            //record.StpGroupEfficiency = canonicalAlgorithm.StpGroupEfficiency;

            frictionHeadCell.Value = canonicalAlgorithm.WorkingFrictionHead.ToString("f6");

            row.Cells.Add(workFlowCell);
            row.Cells.Add(presureInCell);
            row.Cells.Add(presureOutCell);
            row.Cells.Add(electricCurrentCell);
            row.Cells.Add(voltageCell);
            row.Cells.Add(powerCell);
            row.Cells.Add(workHeadCell);
            row.Cells.Add(speedCell);
            row.Cells.Add(temperatureCell);
            row.Cells.Add(stpQCell);
            row.Cells.Add(stpHeadCell);
            row.Cells.Add(stpShaftPowerCell);
            row.Cells.Add(stpPumpEfficiencyCell);
            //row.Cells.Add(stpHeadCell);
            row.Cells.Add(stpGroupEfficiencyCell);
            row.Cells.Add(staticHeadCell);
            row.Cells.Add(dynamicHeadHeadCell);
            row.Cells.Add(geoHeadHeadCell);
            row.Cells.Add(frictionHeadCell);

            this.experiment.RecordList.Add(record);
            this.dataGridView.Rows.Add(row);

            //计算和重画报表
            caculateAndReDrawReport();
        }
#endif
        #endregion







     
       

       

        private void deleteSelectedItem()
        {
            DataGridViewSelectedRowCollection selectedRows = this.dataGridView.SelectedRows;

            if (selectedRows.Count == 0)
            {
                return;
            }

            if (MessageBox.Show("请确认是否删除当前记录", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                int[] ids = new int[selectedRows.Count];

                for (int i = 0; i < selectedRows.Count; i++)
                {
                    if (selectedRows[i].Tag == null)
                    {
                        ids[i] = -1;
                        continue;
                    }
                    PerfExperimentRecord record = (PerfExperimentRecord)selectedRows[i].Tag;
                    ids[i] = record.Id;
                    this.dataGridView.Rows.Remove(selectedRows[i]);
                    this.experiment.RecordList.Remove(record);
                }
                this.service.RemoveExperimentRecordByIds(ids);
                caculateAndReDrawReport();
                this.dataGridView.ClearSelection();
                refreshIdCell();
            }
        }

        private void finishExperiment()
        {
            if (this.experiment.RecordList.Count == 0)
            {
                if (DialogResult.Cancel == MessageBox.Show("试验未完成，是否退出?", "退出试验", MessageBoxButtons.OKCancel))
                {
                    return;
                }
            }
            else  if (DialogResult.Yes == MessageBox.Show("是否保存数据？", "退出试验", MessageBoxButtons.YesNo))
            {
#if TEST
                testIndex = 0;
#else
                this.EndRead();
#endif
                caculateResult();
                String chartPath = Config.PerfExperimentChartImageDir + "\\" + this.experiment.Code + ".png";
                this.chart.SaveImage(chartPath, ChartImageFormat.Png);
                this.experiment.FilePath = excelManager.SaveExperiment(this.experiment, chartPath);
                this.service.SaveExperimentFilePath(this.experiment);
                
            }
            else
            {
                this.service.DeleteExperiment(this.experiment.Code);
            }
            this.experiment = null;
            this.ExperimentIsRunning = false;
            this.statueRefresh();
            this.textBoxSSLL.Text = "";
            this.textBoxCKYL.Text = "";
            this.textBoxDJZS.Text = "";
            this.textBoxDL.Text = "";
            this.textBoxDY.Text = "";
            this.textBoxGDZS.Text = "";
            this.textBoxDL.Text = "";
            this.textBoxDY.Text = "";
            this.textBoxGDZS.Text = "";
            this.textBoxGLYS.Text = "";
            this.textBoxJKYL.Text = "";
            this.textBoxJZXL.Text = "";
            this.textBoxSSLL.Text = "";
            this.textBoxWD.Text = "";
            this.textBoxXiaoLv.Text = "";
            this.textBoxYangCheng.Text = "";
            this.textBoxZGL.Text = "";
            this.textBoxZHLL.Text = "";
            this.textBoxZHYC.Text = "";
            this.textBoxYGGL.Text = "";
            this.textBoxZHGL.Text = "";
        }



        #endregion

        #region  注释 

        private void caculateResult()
        {
            List<PerfExperimentRecord> list = this.experiment.RecordList;
            if (list == null || list.Count == 0)
            {
                return;
            }

            Double[] qList = new Double[list.Count];
            Double[] hList = new Double[list.Count];
            Double[] pList = new Double[list.Count];
            Double[] eList = new Double[list.Count];

            Double minQ, maxQ;
            minQ = Double.MaxValue;
            maxQ = Double.MinValue;

            //最终报表中展示的都是标况下的数据
            for (int i = 0; i < list.Count; i++)
            {
                qList[i] = list[i].StpFlow;
                hList[i] = list[i].StpHead;
                pList[i] = list[i].StpShaftPower;
                eList[i] = list[i].StpPumpEfficiency;

                if (qList[i] - maxQ > Double.Epsilon)
                {
                    maxQ = qList[i];
                }
                if (minQ - qList[i] > Double.Epsilon)
                {
                    minQ = qList[i];
                }
            }

            Double[] paramH = CanonicalAlgorithm.Solve(qList, hList);
            Double[] paramP = CanonicalAlgorithm.Solve(qList, pList);
            Double[] paramE = CanonicalAlgorithm.Solve(qList, eList);
            //根据拟合曲线方程代入额定扬程，计算流量
            Double resultFlow = CanonicalAlgorithm.caculateResultFlowValue(paramH, this.experiment.DesignHead, minQ, maxQ);

            bool flowLevel = CanonicalAlgorithm.JudgeFlowLevel(resultFlow, this.experiment.DesignFlow, this.experiment.ExperimentLevel);
            this.experiment.ExperimentResultFlow = (float)resultFlow;
            this.experiment.ExperimentResultEffIsPass = flowLevel ? 1 : 0;

            //代入额定流量，代入拟合方程，求出拟合曲线上的扬程
            Double curveHead = CanonicalAlgorithm.caculateValue(this.experiment.DesignFlow, paramH);
            bool headLevel = CanonicalAlgorithm.JudgeHeadLevel(curveHead, this.experiment.DesignHead, this.experiment.ExperimentLevel);
            this.experiment.ExperimentResultHead = (float)curveHead;
            this.experiment.ExperimentResultHeadIsPass = headLevel ? 1 : 0;

            //代入额定流量，求出拟合曲线上的功率
            Double curvePower = CanonicalAlgorithm.caculateValue(this.experiment.DesignHead, paramP);
            bool powerLevel = CanonicalAlgorithm.JudgePowerLevel(curvePower, this.experiment.DesignShaftPower, this.experiment.ExperimentLevel);
            this.experiment.ExperimentResultPower = (float)curvePower;
            this.experiment.ExperimentResultPowerIsPass = powerLevel ? 1 : 0;

            //代入额定流量，求出拟合曲线上的效率
            Double curveEff = CanonicalAlgorithm.caculateValue(this.experiment.DesignHead, paramE);
            bool effLevel = CanonicalAlgorithm.JudgePowerLevel(curveEff, this.experiment.DesignPumpEfficiency, this.experiment.ExperimentLevel);
            this.experiment.ExperimentResultEff = (float)curveEff;
            this.experiment.ExperimentResultEffIsPass = effLevel ? 1 : 0;

            Double[] crossValue = CanonicalAlgorithm.CaculateCrossFlowHead(this.experiment.DesignFlow, this.experiment.DesignHead, maxQ, paramH);
            Double flow = Double.NaN;
            Double head = Double.NaN;
            if (crossValue != null)
            {
                flow = crossValue[0];
                head = crossValue[1];
            }

            this.experiment.CrossFlow = flow;
            this.experiment.CrossHead = head;


        }

        private void WinTimer_Tick(object sender, EventArgs e)
        {
            float presureIn = plc.readVData(100);
            float presureOut = plc.readVData(110);
            float flow = plc.readVData(210); //plc.readVData(experiment.FlowmeterAddress);
            float temperature = plc.readVData(180);
            float speed = plc.readVData(190);
            ushort[] meanData = modBus.ReadHoldingRegisters(1, 544, 20);

            float dianya = getValue(meanData[0], meanData[1]);
            float dianliu = getValue(meanData[2], meanData[3]) * (float)this.experiment.CurrentTransformationRatio;
            float yggl = getValue(meanData[4], meanData[5]) * (float)this.experiment.CurrentTransformationRatio;
            //float wggl = getValue(meanData[6], meanData[7])*(float)this.experiment.CurrentTransformationRatio;//无功功率
            //float szgl = getValue(meanData[8], meanData[9])*(float)this.experiment.CurrentTransformationRatio;//视在功率
            float glys = getValue(meanData[10], meanData[11]);//功率因素

            this.textBoxJKYL.Text = presureIn.ToString("F2");
            this.textBoxCKYL.Text = presureOut.ToString("F2");
            this.textBoxSSLL.Text = flow.ToString("F2");
            this.textBoxWD.Text = temperature.ToString("F2");
            this.textBoxDJZS.Text = speed.ToString("F2");
            this.textBoxDL.Text = dianliu.ToString("F2");
            this.textBoxDY.Text = dianya.ToString("F2");
            this.textBoxYGGL.Text = (yggl / 1000.0).ToString("F2");
            //this.textBoxWGGL.Text = wggl.ToString();
            //this.textBoxSZGL.Text = szgl.ToString();
            this.textBoxGLYS.Text = glys.ToString("F2");

            PerfExperimentRecord record = caculateExperimentRecord(presureIn, presureOut, flow, temperature, speed, dianya, dianliu, yggl, glys);
            //赋值
            this.currentPerfExperimentRecord = record;

            this.textBoxGDZS.Text = this.experiment.DesignRatedSpeed.ToString();
            this.textBoxZHYC.Text = record.StpHead.ToString("F2");
            this.textBoxZHLL.Text = record.StpFlow.ToString("F2");
            this.textBoxZHGL.Text = (record.StpPowerIn / 1000.0).ToString("F2");
            this.textBoxZGL.Text = (record.StpShaftPower / 1000.0).ToString("F2");
            this.textBoxJZXL.Text = record.StpGroupEfficiency.ToString("F2");
            this.textBoxXiaoLv.Text = record.StpPumpEfficiency.ToString("F2");
            this.textBoxYangCheng.Text = record.WorkingHead.ToString("F2");


        }


        private PerfExperimentRecord readRecord()
        {
            PerfExperimentRecord record = null;
            lock (lockObject)
            {
                record = this.currentPerfExperimentRecord;
            }
            if (record == null)
            {
                //MessageBox.Show("正在读取数据，请稍后再试!");
                return null;
            }
            this.experiment.RecordList.Add(record);
            return record;
        }


        private void fetchRecordToDataGridView()
        {
            PerfExperimentRecord record = readRecord();
            record.RecordTime = DateTime.Now;
            this.experiment.RecordList.Add(record);
            fetchRecordToDataGridViewFromRecord(record);
        }

        private void StartRead()
        {
            if (!plc.IsConnected)
            {
                plc.Connect();
            }
            if (!modBus.IsOpen)
            {
                modBus.Open();
            }
            //timer.Enabled = true;
            winTimer.Start();

        }

        private void EndRead()
        {
            if (plc.IsConnected)
            {
                plc.Close();
            }
            if (modBus.IsOpen)
            {
                modBus.Close();
            }
            //timer.Enabled = false;
            winTimer.Stop();

        }



        class ChartDataInfo
        {

        }

        private float getValue(ushort data1, ushort data2)
        {
            byte[] b = new byte[4];
            b[0] = (byte)(data1 >> 8);
            b[1] = (byte)data1;
            b[2] = (byte)(data2 >> 8);
            b[3] = (byte)data2;
            /// byte[] byteTemp = new byte[4] { b[0], b[1], b[2], b[3] };
            byte[] byteTemp = new byte[4] { b[3], b[2], b[1], b[0] };

            return BitConverter.ToSingle(byteTemp, 0);
        }

        private ChartDataInfo caculateChartData(Double ratedFlow, Double ratedHead, Double ratedPower, Double rateEff, String level, Double[] qDatalist, Double[] hDataList, Double[] pDataList, Double[] eDataList, Double[] paramH, Double[] paramP, Double[] paramE)
        {
            int xUnitCount = XAxisUnit;
            int yUnitCount = YAxisUnit;
            double axisMaxRate = AxisMaxRate;
            int drawPointCount = DrawPointCount;

            int count = qDatalist.Length;

            ChartDataInfo chartDataInfo = new ChartDataInfo();

            //获取最小流量和最大流量
            double maxQ = 0.0f;
            double minQ = Double.MaxValue;

            //获取扬程的最大值和最小值
            Double maxHY = 0.0f;
            Double minHY = Double.MaxValue;

            //获取Y轴数据的最大值和最小值
            Double maxPY = 0.0f;
            Double minPY = Double.MaxValue;



            List<Double[]> hPointList = new List<double[]>();
            List<Double[]> pPointList = new List<double[]>();
            List<Double[]> ePointList = new List<double[]>();

            for (int i = 0; i < count; i++)
            {
                Double q = qDatalist[i];

                //流量最大值和最小值
                double delta = q - maxQ;
                if (delta >= 0.0001)
                {
                    maxQ = q;
                }
                delta = q - minQ;
                if (delta <= -0.0001)
                {
                    minQ = q;
                }

                //扬程最大值和最小值
                Double hy = (Double)hDataList[i];
                delta = hy - maxHY;
                if (delta >= 0.0001)
                {
                    maxHY = hy;
                }
                delta = hy - minHY;
                if (delta <= -0.0001)
                {
                    minHY = hy;
                }

                //功率最大最小值
                Double py = (Double)pDataList[i];
                delta = py - maxPY;
                if (delta >= 0.0001)
                {
                    maxPY = py;
                }
                delta = py - minPY;
                if (delta <= -0.0001)
                {
                    minPY = py;
                }


                hPointList.Add(new double[] { q, hy });
                pPointList.Add(new double[] { q, py });
                ePointList.Add(new double[] { q, eDataList[i] });
            }


            //求出最大值，并且做一个坐标余量的计算。
            Double maxXQAxis = maxQ / axisMaxRate;
            Double maxHYAxis = maxHY / axisMaxRate;
            Double maxPYAxis = maxPY / axisMaxRate;
            //最大效率为100
            //Double maxEYAxis = 100.0;

            //根据功率和效率的最大值，求出功率和效率在坐标上的比率（功率效率曲线展示在一条Y轴上）
            //Double peRate = maxPYAxis / maxEYAxis;

            //坐标轴每一段单元的长度
            double xQDoubleUnit = maxXQAxis / xUnitCount;
            double yPDoubleUnit = maxPYAxis / yUnitCount;
            double yHDoubleUnit = maxHYAxis / yUnitCount;

            if (xQDoubleUnit - 1.0 > 0.001)
            {
                xQDoubleUnit = (Double)(int)xQDoubleUnit;
            }
            else
            {
                xQDoubleUnit = (Double)(int)(xQDoubleUnit * 100) / 100.0f;
            }

            if (yHDoubleUnit - 1.0 > 0.001)
            {
                yHDoubleUnit = (Double)(int)yHDoubleUnit;
            }
            else
            {
                yHDoubleUnit = (Double)(int)(yHDoubleUnit * 100) / 100.0f;
            }

            if (yPDoubleUnit - 1.0 > 0.001)
            {
                yPDoubleUnit = (Double)(int)yPDoubleUnit;
            }
            else
            {
                yPDoubleUnit = (Double)(int)(yPDoubleUnit * 100) / 100.0f;
            }

            //设置报表设置的参数
            chartDataInfo.MinXQAxis = 0.0f;
            chartDataInfo.MaxXQAxis = maxXQAxis;
            chartDataInfo.MinYHAxis = 0.0f;
            chartDataInfo.MaxYHAxis = maxHYAxis;
            chartDataInfo.MinYPAxis = 0.0f;
            chartDataInfo.MaxYPAxis = maxPYAxis;


            chartDataInfo.AxisXQInterval = xQDoubleUnit;
            chartDataInfo.AxisYHInterval = yHDoubleUnit;
            chartDataInfo.AxisYPInterval = yPDoubleUnit;
            chartDataInfo.AxisYEInterval = chartDataInfo.MaxYEAxis / yUnitCount;


            chartDataInfo.XUnitCount = xUnitCount;
            chartDataInfo.YUnitCount = yUnitCount;
            chartDataInfo.XRatedQ = this.experiment.DesignFlow;
            chartDataInfo.YRatedHead = this.experiment.DesignHead;
            chartDataInfo.YRatedPower = this.experiment.DesignShaftPower;
            chartDataInfo.YRatedEff = this.experiment.DesignPumpEfficiency;


            //根据公式，平均选取30个点，用于报表中画曲线的点
            Double[] xValue = new Double[drawPointCount + 1];
            Double[] yhValue = new Double[drawPointCount + 1];
            Double[] ypValue = new Double[drawPointCount + 1];
            Double[] yeValue = new Double[drawPointCount + 1];
            double dd = (maxQ - minQ) / drawPointCount;
            for (int i = 0; i <= drawPointCount; i++)
            {
                xValue[i] = minQ + i * dd;
                Double q = xValue[i];
                yhValue[i] = CanonicalAlgorithm.caculateValue(q, paramH);
                ypValue[i] = CanonicalAlgorithm.caculateValue(q, paramP);
                yeValue[i] = CanonicalAlgorithm.caculateValue(q, paramE);

            }
            chartDataInfo.DrawXQList = new ArrayList(xValue);
            chartDataInfo.DrawYHList = new ArrayList(yhValue);
            chartDataInfo.DrawYPList = new ArrayList(ypValue);
            chartDataInfo.DrawYEList = new ArrayList(yeValue);

            chartDataInfo.InputQHPoints = hPointList;
            chartDataInfo.InputQPPoints = pPointList;
            chartDataInfo.InputQEPoints = ePointList;

            chartDataInfo.FlowHeadRange = CanonicalAlgorithm.GetFlowHeadRange(ratedFlow, ratedHead, level);
            chartDataInfo.FlowPowerRange = CanonicalAlgorithm.GetFlowPowerRange(ratedFlow, ratedPower, level);
            chartDataInfo.FlowEffRange = CanonicalAlgorithm.GetFlowEffRange(ratedFlow, rateEff, level);


            return chartDataInfo;
        }
        /// <summary>
        /// 流量扬程，流量功率，流量效率三个图合并在一起展示所需要的计算
        /// </summary>
        /// <param name="qDatalist"></param>
        /// <param name="hDataList"></param>
        /// <param name="pDataList"></param>
        /// <param name="eDataList"></param>
        /// <param name="paramH"></param>
        /// <param name="paramP"></param>
        /// <param name="paramE"></param>
        /// <returns></returns>
        private ChartDataInfo caculateChartData4MergeShow(Double[] qDatalist, Double[] hDataList, Double[] pDataList, Double[] eDataList, Double[] paramH, Double[] paramP, Double[] paramE)
        {
            int xUnitCount = XAxisUnit;
            int yUnitCount = YAxisUnit;
            double axisMaxRate = AxisMaxRate;
            int drawPointCount = DrawPointCount;

            int count = qDatalist.Length;

            ChartDataInfo chartDataInfo = new ChartDataInfo();

            //获取最小流量和最大流量
            double maxQ = 0.0f;
            double minQ = Double.MaxValue;

            //获取扬程的最大值和最小值
            Double maxHY = 0.0f;
            Double minHY = Double.MaxValue;

            //获取Y轴数据的最大值和最小值
            Double maxPY = 0.0f;
            Double minPY = Double.MaxValue;

            Double maxEY = 0.0f;
            Double minEY = Double.MaxValue;

            List<Double[]> hPointList = new List<double[]>();
            List<Double[]> pPointList = new List<double[]>();
            List<Double[]> ePointList = new List<double[]>();

            for (int i = 0; i < count; i++)
            {
                Double q = qDatalist[i];

                //流量最大值和最小值
                double delta = q - maxQ;
                if (delta >= 0.0001)
                {
                    maxQ = q;
                }
                delta = q - minQ;
                if (delta <= -0.0001)
                {
                    minQ = q;
                }

                //扬程最大值和最小值
                Double hy = (Double)hDataList[i];
                delta = hy - maxHY;
                if (delta >= 0.0001)
                {
                    maxHY = hy;
                }
                delta = hy - minHY;
                if (delta <= -0.0001)
                {
                    minHY = hy;
                }

                //功率最大最小值
                Double py = (Double)pDataList[i];
                delta = py - maxPY;
                if (delta >= 0.0001)
                {
                    maxPY = py;
                }
                delta = py - minPY;
                if (delta <= -0.0001)
                {
                    minPY = py;
                }

                //效率最大最小值
                Double ey = (Double)eDataList[i];
                delta = ey - maxEY;
                if (delta >= 0.0001)
                {
                    maxEY = ey;
                }
                delta = ey - minEY;
                if (delta <= -0.0001)
                {
                    minEY = ey;
                }
                hPointList.Add(new double[] { q, hy });
                pPointList.Add(new double[] { q, py });
                ePointList.Add(new double[] { q, ey });
            }


            //求出最大值，并且做一个坐标余量的计算。
            Double maxXQAxis = maxQ / axisMaxRate;
            Double maxHYAxis = maxHY / axisMaxRate;
            Double maxPYAxis = maxPY / axisMaxRate;
            //最大效率为100
            Double maxEYAxis = maxEY / axisMaxRate;

            //根据功率和效率的最大值，求出功率和效率在坐标上的比率（功率效率曲线展示在一条Y轴上）
            Double peRate = maxPYAxis / maxEYAxis;

            //坐标轴每一段单元的长度
            double xQDoubleUnit = maxXQAxis / xUnitCount;
            double yPDoubleUnit = maxPYAxis / yUnitCount;
            double yHDoubleUnit = maxHYAxis / yUnitCount;
            if (xQDoubleUnit - 1.0 > 0.001)
            {
                xQDoubleUnit = (Double)(int)xQDoubleUnit;
            }
            else
            {
                xQDoubleUnit = (Double)(int)(xQDoubleUnit * 100) / 100.0f;
            }

            if (yHDoubleUnit - 1.0 > 0.001)
            {
                yHDoubleUnit = (Double)(int)yHDoubleUnit;
            }
            else
            {
                yHDoubleUnit = (Double)(int)(yHDoubleUnit * 100) / 100.0f;
            }

            if (yPDoubleUnit - 1.0 > 0.001)
            {
                yPDoubleUnit = (Double)(int)yPDoubleUnit;
            }
            else
            {
                yPDoubleUnit = (Double)(int)(yPDoubleUnit * 100) / 100.0f;
            }

            //设置报表设置的参数
            chartDataInfo.MinXQAxis = 0.0f;
            chartDataInfo.MaxXQAxis = maxXQAxis;
            chartDataInfo.MinYHAxis = 0.0f;
            chartDataInfo.MaxYHAxis = maxHYAxis;
            chartDataInfo.MinYPAxis = 0.0f;
            chartDataInfo.MaxYPAxis = maxPYAxis;
            chartDataInfo.AxisXQInterval = xQDoubleUnit;
            chartDataInfo.AxisYHInterval = yHDoubleUnit;
            chartDataInfo.AxisYPInterval = yPDoubleUnit;
            chartDataInfo.PeRate = peRate;
            chartDataInfo.XUnitCount = xUnitCount;
            chartDataInfo.YUnitCount = yUnitCount;
            chartDataInfo.XRatedQ = this.experiment.DesignFlow;
            chartDataInfo.YRatedHead = this.experiment.DesignHead;
            chartDataInfo.YRatedPower = this.experiment.DesignShaftPower;
            chartDataInfo.YRatedEff = this.experiment.DesignPumpEfficiency;


            //根据公式，平均选取30个点，用于报表中画曲线的点
            Double[] xValue = new Double[drawPointCount + 1];
            Double[] yhValue = new Double[drawPointCount + 1];
            Double[] ypValue = new Double[drawPointCount + 1];
            Double[] yeValue = new Double[drawPointCount + 1];
            double dd = (maxQ - minQ) / drawPointCount;
            for (int i = 0; i <= drawPointCount; i++)
            {
                xValue[i] = minQ + i * dd;
                Double q = xValue[i];
                yhValue[i] = CanonicalAlgorithm.caculateValue(q, paramH);
                ypValue[i] = CanonicalAlgorithm.caculateValue(q, paramP);
                yeValue[i] = peRate * CanonicalAlgorithm.caculateValue(q, paramE);
                //hpValue[i] = param[0] * Math.Pow(q, 4) + param[1] * Math.Pow(q, 3) + param[2] * Math.Pow(q, 2) + param[3] * Math.Pow(q, 1) + param[4] * Math.Pow(q, 0);
                //ypValue[i] = param[0] * Math.Pow(q, 4) + param[1] * Math.Pow(q, 3) + param[2] * Math.Pow(q, 2) + param[3] * Math.Pow(q, 1) + param[4] * Math.Pow(q, 0);

                //按比例缩放
                //yeValue[i] = peRate * (param[0] * Math.Pow(q, 4) + param[1] * Math.Pow(q, 3) + param[2] * Math.Pow(q, 2) + param[3] * Math.Pow(q, 1) + param[4] * Math.Pow(q, 0));

            }
            chartDataInfo.DrawXQList = new ArrayList(xValue);
            chartDataInfo.DrawYHList = new ArrayList(yhValue);
            chartDataInfo.DrawYPList = new ArrayList(ypValue);
            chartDataInfo.DrawYEList = new ArrayList(yeValue);

            chartDataInfo.InputQHPoints = hPointList;
            chartDataInfo.InputQPPoints = pPointList;
            chartDataInfo.InputQEPoints = ePointList;


            return chartDataInfo;
        }

        private void DrawChart(ChartDataInfo chartDatainfo)
        {
            Axis axisQX = this.chart.ChartAreas["perf"].AxisX;
            Axis axisHY = this.chart.ChartAreas["perf"].AxisY;
            Axis axisQX2 = this.chart.ChartAreas["powerChart"].AxisX;
            Axis axisPY = this.chart.ChartAreas["powerChart"].AxisY;
            Axis axisQX3 = this.chart.ChartAreas["effChart"].AxisX;
            Axis axisEY = this.chart.ChartAreas["effChart"].AxisY;

            axisQX.Maximum = chartDatainfo.MaxXQAxis;
            axisQX.Minimum = chartDatainfo.MinXQAxis;
            axisQX2.Maximum = chartDatainfo.MaxXQAxis;
            axisQX2.Minimum = chartDatainfo.MinXQAxis;
            axisQX3.Maximum = chartDatainfo.MaxXQAxis;
            axisQX3.Minimum = chartDatainfo.MinXQAxis;
            axisPY.Maximum = chartDatainfo.MaxYPAxis;
            axisPY.Minimum = chartDatainfo.MinYPAxis;
            axisHY.Maximum = chartDatainfo.MaxYHAxis;
            axisHY.Minimum = chartDatainfo.MinYHAxis;
            axisEY.Maximum = chartDatainfo.MaxYEAxis;
            axisEY.Minimum = chartDatainfo.MinYEAxis;

            axisQX.Interval = chartDatainfo.AxisXQInterval;
            axisQX2.Interval = chartDatainfo.AxisXQInterval;
            axisQX3.Interval = chartDatainfo.AxisXQInterval;
            axisPY.Interval = chartDatainfo.AxisYPInterval;
            axisEY.Interval = chartDatainfo.AxisYEInterval;
            axisHY.Interval = chartDatainfo.AxisYHInterval;
            chart.Series["流量扬程曲线"].Points.Clear();
            chart.Series["流量功率曲线"].Points.Clear();
            chart.Series["流量效率曲线"].Points.Clear();

            chart.Series["流量扬程曲线"].Points.DataBindXY(chartDatainfo.DrawXQList, chartDatainfo.DrawYHList);
            chart.Series["流量功率曲线"].Points.DataBindXY(chartDatainfo.DrawXQList, chartDatainfo.DrawYPList);
            chart.Series["流量效率曲线"].Points.DataBindXY(chartDatainfo.DrawXQList, chartDatainfo.DrawYEList);
            chart.Series["QHPoint"].Points.Clear();
            chart.Series["QPPoint"].Points.Clear();
            chart.Series["QEPoint"].Points.Clear();


            for (int i = 0; i < chartDatainfo.InputQEPoints.Count; i++)
            {
                double[] qePoints = chartDatainfo.InputQEPoints[i];
                double[] qhPoints = chartDatainfo.InputQHPoints[i];
                double[] qpPoints = chartDatainfo.InputQPPoints[i];
                chart.Series["QHPoint"].Points.Add(new DataPoint(qhPoints[0], qhPoints[1]));
                chart.Series["QPPoint"].Points.Add(new DataPoint(qpPoints[0], qpPoints[1]));
                chart.Series["QEPoint"].Points.Add(new DataPoint(qePoints[0], qePoints[1]));
            }

            //chart.Series["流量扬程辅助判定线"].Points.Clear();
            //chart.Series["流量功率辅助判定线"].Points.Clear();
            //chart.Series["流量效率辅助判定线"].Points.Clear();
            double[] zeroPoint = new double[] { 0, 0 };
            double[] headPoint = new double[] { chartDatainfo.XRatedQ, chartDatainfo.YRatedHead };
            double[] powerPoint = new double[] { chartDatainfo.XRatedQ, chartDatainfo.YRatedPower };
            double[] effPoint = new double[] { chartDatainfo.XRatedQ, chartDatainfo.YRatedEff };

            ArrayList flowXList = new ArrayList();
            flowXList.Add(0.0f);
            flowXList.Add(chartDatainfo.XRatedQ);
            ArrayList headYList = new ArrayList();
            headYList.Add(0.0f);
            headYList.Add(chartDatainfo.YRatedHead);
            ArrayList powerYList = new ArrayList();
            powerYList.Add(0.0f);
            powerYList.Add(chartDatainfo.YRatedPower);
            ArrayList effYList = new ArrayList();
            effYList.Add(0.0f);
            effYList.Add(chartDatainfo.YRatedEff);
            chart.Series["流量扬程辅助判定线"].Points.DataBindXY(flowXList, headYList);
            chart.Series["流量功率辅助判定线"].Points.DataBindXY(flowXList, powerYList);
            chart.Series["流量效率辅助判定线"].Points.DataBindXY(flowXList, effYList);


            ArrayList xRatedFlowRange1 = new ArrayList();
            ArrayList xRatedHeadRange = new ArrayList();

            xRatedFlowRange1.Add(chartDatainfo.FlowHeadRange[0, 0]);
            xRatedFlowRange1.Add(chartDatainfo.FlowHeadRange[1, 0]);
            xRatedHeadRange.Add(chartDatainfo.FlowHeadRange[0, 1]);
            xRatedHeadRange.Add(chartDatainfo.FlowHeadRange[1, 1]);

            chart.Series["XFlowHeadRange"].Points.Clear();
            chart.Series["XFlowHeadRange"].Points.DataBindXY(xRatedFlowRange1, xRatedHeadRange);


            ArrayList yRatedFlowRange1 = new ArrayList();
            ArrayList yRatedHeadRange = new ArrayList();

            yRatedFlowRange1.Add(chartDatainfo.FlowHeadRange[2, 0]);
            yRatedFlowRange1.Add(chartDatainfo.FlowHeadRange[3, 0]);
            yRatedHeadRange.Add(chartDatainfo.FlowHeadRange[2, 1]);
            yRatedHeadRange.Add(chartDatainfo.FlowHeadRange[3, 1]);

            chart.Series["YFlowHeadRange"].Points.Clear();
            chart.Series["YFlowHeadRange"].Points.DataBindXY(yRatedFlowRange1, yRatedHeadRange);


            ArrayList xRatedFlowRange2 = new ArrayList();
            ArrayList xRatedPowerRange = new ArrayList();

            xRatedFlowRange2.Add(chartDatainfo.FlowPowerRange[0, 0]);
            xRatedFlowRange2.Add(chartDatainfo.FlowPowerRange[1, 0]);
            xRatedPowerRange.Add(chartDatainfo.FlowPowerRange[0, 1]);
            xRatedPowerRange.Add(chartDatainfo.FlowPowerRange[1, 1]);

            chart.Series["XFlowPowerRange"].Points.Clear();
            chart.Series["XFlowPowerRange"].Points.DataBindXY(xRatedFlowRange2, xRatedPowerRange);


            ArrayList yRatedFlowRange2 = new ArrayList();
            ArrayList yRatedPowerRange = new ArrayList();

            yRatedFlowRange2.Add(chartDatainfo.FlowPowerRange[2, 0]);
            yRatedFlowRange2.Add(chartDatainfo.FlowPowerRange[3, 0]);
            yRatedPowerRange.Add(chartDatainfo.FlowPowerRange[2, 1]);
            yRatedPowerRange.Add(chartDatainfo.FlowPowerRange[3, 1]);

            chart.Series["YFlowPowerRange"].Points.Clear();
            chart.Series["YFlowPowerRange"].Points.DataBindXY(yRatedFlowRange2, yRatedPowerRange);



            ArrayList xRatedFlowRange3 = new ArrayList();
            ArrayList xRatedEffRange = new ArrayList();
            xRatedFlowRange3.Add(chartDatainfo.FlowEffRange[0, 0]);
            xRatedFlowRange3.Add(chartDatainfo.FlowEffRange[1, 0]);
            xRatedEffRange.Add(chartDatainfo.FlowEffRange[0, 1]);
            xRatedEffRange.Add(chartDatainfo.FlowEffRange[1, 1]);
            chart.Series["XFlowEffRange"].Points.Clear();
            chart.Series["XFlowEffRange"].Points.DataBindXY(xRatedFlowRange3, xRatedEffRange);


            ArrayList yRatedFlowRange3 = new ArrayList();
            ArrayList yRatedEffRange = new ArrayList();
            yRatedFlowRange3.Add(chartDatainfo.FlowEffRange[2, 0]);
            yRatedFlowRange3.Add(chartDatainfo.FlowEffRange[3, 0]);
            yRatedEffRange.Add(chartDatainfo.FlowEffRange[2, 1]);
            yRatedEffRange.Add(chartDatainfo.FlowEffRange[3, 1]);
            chart.Series["YFlowEffRange"].Points.Clear();
            chart.Series["YFlowEffRange"].Points.DataBindXY(yRatedFlowRange3, yRatedEffRange);


            /*chart.Series["流量扬程辅助判定线"].Points.Add(new DataPoint(zeroPoint[0],zeroPoint[1]));
            chart.Series["流量扬程辅助判定线"].Points.Add(new DataPoint(headPoint[0],headPoint[1]));

            chart.Series["流量功率辅助判定线"].Points.Add(new DataPoint(zeroPoint[0], zeroPoint[1]));
            chart.Series["流量功率辅助判定线"].Points.Add(new DataPoint(powerPoint[0], powerPoint[1]));


            chart.Series["流量效率辅助判定线"].Points.Add(new DataPoint(zeroPoint[0], zeroPoint[1])); 
            chart.Series["流量效率辅助判定线"].Points.Add(new DataPoint(effPoint[0], effPoint[1]));*/
        }

        private void DrawChart(String chartAreaName, ChartDataInfo chartDatainfo)
        {
            Axis axisQX = this.chart.ChartAreas[chartAreaName].AxisX;
            Axis axisHY = this.chart.ChartAreas[chartAreaName].AxisY;
            Axis axisQX2 = this.chart.ChartAreas[chartAreaName].AxisX2;
            Axis axisPY = this.chart.ChartAreas[chartAreaName].AxisY2;
            Axis axisQX3 = this.chart.ChartAreas[chartAreaName].AxisX2;
            Axis axisEY = this.chart.ChartAreas[chartAreaName].AxisY2;

            axisQX.Maximum = chartDatainfo.MaxXQAxis;
            axisQX.Minimum = chartDatainfo.MinXQAxis;
            axisQX2.Maximum = chartDatainfo.MaxXQAxis;
            axisQX2.Minimum = chartDatainfo.MinXQAxis;
            axisQX3.Maximum = chartDatainfo.MaxXQAxis;
            axisQX3.Minimum = chartDatainfo.MinXQAxis;
            axisPY.Maximum = chartDatainfo.MaxYPAxis;
            axisPY.Minimum = chartDatainfo.MinYPAxis;
            axisHY.Maximum = chartDatainfo.MaxYHAxis;
            axisHY.Minimum = chartDatainfo.MinYHAxis;
            axisEY.Maximum = chartDatainfo.MaxYPAxis;
            axisEY.Minimum = chartDatainfo.MinYPAxis;



            axisQX.Interval = chartDatainfo.AxisXQInterval;
            axisQX2.Interval = chartDatainfo.AxisXQInterval;
            axisQX3.Interval = chartDatainfo.AxisXQInterval;
            axisPY.Interval = chartDatainfo.AxisYPInterval;
            axisEY.Interval = chartDatainfo.AxisYPInterval;
            axisHY.Interval = chartDatainfo.AxisYHInterval;

            chart.Series["流量扬程曲线"].Points.DataBindXY(chartDatainfo.DrawXQList, chartDatainfo.DrawYHList);
            chart.Series["流量功率曲线"].Points.DataBindXY(chartDatainfo.DrawXQList, chartDatainfo.DrawYPList);
            chart.Series["流量效率曲线"].Points.DataBindXY(chartDatainfo.DrawXQList, chartDatainfo.DrawYEList);
            chart.Series["QHPoint"].Points.Clear();
            chart.Series["QPPoint"].Points.Clear();
            chart.Series["QEPoint"].Points.Clear();
            for (int i = 0; i < chartDatainfo.InputQEPoints.Count; i++)
            {
                double[] qePoints = chartDatainfo.InputQEPoints[i];
                double[] qhPoints = chartDatainfo.InputQHPoints[i];
                double[] qpPoints = chartDatainfo.InputQPPoints[i];
                chart.Series["QHPoint"].Points.Add(new DataPoint(qhPoints[0], qhPoints[1]));
                chart.Series["QPPoint"].Points.Add(new DataPoint(qpPoints[0], qpPoints[1]));
                chart.Series["QEPoint"].Points.Add(new DataPoint(qePoints[0], chartDatainfo.PeRate * qePoints[1]));
            }
        }

        private void ReDrawChart()
        {
            //this.chart.Series.Clear();
            chart.Series["QHPoint"].Points.Clear();
            chart.Series["QPPoint"].Points.Clear();
            chart.Series["QEPoint"].Points.Clear();
        }

        private void caculateAndReDrawReport()
        {
            List<PerfExperimentRecord> list = this.experiment.RecordList;


            Double[] qList = new Double[list.Count];
            Double[] hList = new Double[list.Count];
            Double[] pList = new Double[list.Count];
            Double[] eList = new Double[list.Count];

            //最终报表中展示的都是标况下的数据
            for (int i = 0; i < list.Count; i++)
            {
                qList[i] = list[i].StpFlow;
                hList[i] = list[i].StpHead;
                pList[i] = list[i].StpShaftPower;
                eList[i] = list[i].StpPumpEfficiency;
            }

            Double[] paramH = CanonicalAlgorithm.Solve(qList, hList);
            Double[] paramP = CanonicalAlgorithm.Solve(qList, pList);
            Double[] paramE = CanonicalAlgorithm.Solve(qList, eList);

            if (list.Count != 0)
            {
                ChartDataInfo chartDataInfo = caculateChartData(this.experiment.DesignFlow, this.experiment.DesignHead, this.experiment.DesignShaftPower, this.experiment.DesignPumpEfficiency,
                    this.experiment.ExperimentLevel,
                    qList, hList, pList, eList, paramH, paramP, paramE);
                //DrawChart("perf", chartDataInfo)
                DrawChart(chartDataInfo);
            }
            else
            {
                ReDrawChart();
            }

        }
        private void fetchRecordToDataGridViewFromRecord(PerfExperimentRecord record)
        {
            record.ExperimentCode = this.experiment.Code;
            DataGridViewRow row = (DataGridViewRow)this.dataGridView.RowTemplate.Clone();

            DataGridViewTextBoxCell idCell = new DataGridViewTextBoxCell();
            idCell.Value = 0;

            DataGridViewTextBoxCell workFlowCell = new DataGridViewTextBoxCell();
            workFlowCell.Value = record.WorkFlow.ToString("f6");

            DataGridViewTextBoxCell presureInCell = new DataGridViewTextBoxCell();
            presureInCell.Value = record.PresureIn.ToString("f6");

            DataGridViewTextBoxCell presureOutCell = new DataGridViewTextBoxCell();
            presureOutCell.Value = record.PresureOut.ToString("f6");

            DataGridViewTextBoxCell voltageCell = new DataGridViewTextBoxCell();
            voltageCell.Value = record.Voltage.ToString("f6");

            DataGridViewTextBoxCell electricCurrentCell = new DataGridViewTextBoxCell();
            electricCurrentCell.Value = record.ElectricCurrent.ToString("f6");

            DataGridViewTextBoxCell powerCell = new DataGridViewTextBoxCell();
            powerCell.Value = record.WorkingPower.ToString("f6");

            DataGridViewTextBoxCell speedCell = new DataGridViewTextBoxCell();
            speedCell.Value = record.WorkingSpeed.ToString("f6");

            DataGridViewTextBoxCell temperatureCell = new DataGridViewTextBoxCell();
            temperatureCell.Value = record.Temperature.ToString("f6");


            //CanonicalAlgorithm canonicalAlgorithm = new CanonicalAlgorithm(zInlet, zOutlet, kInlet, kInlet, dInlet, dOutlet, lInlet, lOutlet, efficiency, stpRotarySpeed);
            //canonicalAlgorithm.setplcEnvData(record.Temperature, record.PresureIn, record.PresureOut, record.Power, record.Flow, (int)record.Speed);



            DataGridViewTextBoxCell stpQCell = new DataGridViewTextBoxCell();
            stpQCell.Value = record.StpFlow.ToString("f6");

            DataGridViewTextBoxCell workHeadCell = new DataGridViewTextBoxCell();
            workHeadCell.Value = record.WorkingHead.ToString("f6");

            DataGridViewTextBoxCell stpHeadCell = new DataGridViewTextBoxCell();
            stpHeadCell.Value = record.StpHead.ToString("f6");

            DataGridViewTextBoxCell stpShaftPowerCell = new DataGridViewTextBoxCell();
            stpShaftPowerCell.Value = record.StpShaftPower.ToString("f6");

            DataGridViewTextBoxCell stpPumpEfficiencyCell = new DataGridViewTextBoxCell();
            stpPumpEfficiencyCell.Value = record.StpPumpEfficiency.ToString("f6");

            DataGridViewTextBoxCell stpGroupEfficiencyCell = new DataGridViewTextBoxCell();
            stpGroupEfficiencyCell.Value = record.StpGroupEfficiency.ToString("f6");

            DataGridViewTextBoxCell staticHeadCell = new DataGridViewTextBoxCell();
            staticHeadCell.Value = record.WorkingStaticHead.ToString("f6");

            DataGridViewTextBoxCell dynamicHeadHeadCell = new DataGridViewTextBoxCell();
            dynamicHeadHeadCell.Value = record.WorkingDynamicHead.ToString("f6");

            DataGridViewTextBoxCell geoHeadHeadCell = new DataGridViewTextBoxCell();
            geoHeadHeadCell.Value = record.WorkingGeoHead.ToString("f6");

            DataGridViewTextBoxCell frictionHeadCell = new DataGridViewTextBoxCell();
            frictionHeadCell.Value = record.WorkingFrictionHead.ToString("f6");

            row.Cells.Add(idCell);
            row.Cells.Add(workFlowCell);
            row.Cells.Add(presureInCell);
            row.Cells.Add(presureOutCell);
            row.Cells.Add(voltageCell);
            row.Cells.Add(electricCurrentCell);
            row.Cells.Add(powerCell);
            row.Cells.Add(workHeadCell);
            row.Cells.Add(speedCell);
            row.Cells.Add(temperatureCell);
            row.Cells.Add(stpQCell);
            row.Cells.Add(stpHeadCell);
            row.Cells.Add(stpShaftPowerCell);
            row.Cells.Add(stpPumpEfficiencyCell);
            row.Cells.Add(stpGroupEfficiencyCell);
            row.Cells.Add(staticHeadCell);
            row.Cells.Add(dynamicHeadHeadCell);
            row.Cells.Add(geoHeadHeadCell);
            row.Cells.Add(frictionHeadCell);
            row.Tag = record;

            //this.experiment.RecordList.Add(record);
            this.dataGridView.Rows.Add(row);
            this.service.SavePerfExperimentRecord(record);
            refreshIdCell();
            //计算和重画报表
            caculateAndReDrawReport();

        }




        #endregion




        #region 事件代码
        private void MainFrm_Load(object sender, EventArgs e)
        {
            this.dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            this.dataGridView.AutoGenerateColumns = false;            
            tabControl.SelectedIndex = 0;
            this.splitContainer.Panel1Collapsed = false;
            
        }

        
        private void toolStripAddButton_Click(object sender, EventArgs e)
        {
            startExperiment();
        }

        private void ToolStripMenuItemNew_Click(object sender, EventArgs e)
        {

            startExperiment();
        }



        private void toolStripShowDataButton_Click(object sender, EventArgs e)
        {

            this.splitContainer.Panel1Collapsed = true;
            this.toolStripButtonShowList.Visible = true;
            this.toolStripShowDataButton.Visible = false;
            this.toolStripButtonShowList.Enabled = true;
            this.toolStripShowDataButton.Enabled = false;
            this.tabControl.SelectedIndex = 1;
        }
        
        private void toolStripFetchDataButton_Click(object sender, EventArgs e)
        {
            
            //AddRowDataGridview((PLCData)testPLCData[testIndex]);
#if TEST
            ///临时代码
            if (testIndex >= testPLCData.Count)
            {
                return;
            }
            fetchRecordToDataGridView((PLCData)testPLCData[testIndex]);
            testIndex++;
#else
            fetchRecordToDataGridView();
#endif
            
        }
       


        private void ToolStripMenuItemReportSearch_Click(object sender, EventArgs e)
        {
            ExperimentListForm experimentListForm = new ExperimentListForm();
            experimentListForm.ShowDialog();
        }

        private void toolStripDeleteButton_Click(object sender, EventArgs e)
        {        
                deleteSelectedItem();  
        }


        private void toolStripClearButton_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("请确认是否删除当前所有记录", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {

                for (int i = 0; i < this.dataGridView.Rows.Count; i++)
                {
                    object tag = this.dataGridView.Rows[i].Tag;
                    if (tag != null)
                    {
                        this.dataGridView.Rows[i].Selected = true;
                    }

                }
                deleteSelectedItem();
            }
        }

        private void dataGridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            
            if (e.Button == MouseButtons.Right)
            {
                contextMenuStrip.Show(MousePosition.X, MousePosition.Y);
               /* if (e.RowIndex >= 0)
                {
                    //若行已是选中状态就不再进行设置
                    if (dataGridView.Rows[e.RowIndex].Selected == false)
                    {
                        dataGridView.ClearSelection();
                        dataGridView.Rows[e.RowIndex].Selected = true;
                    }
                    //只选中一行时设置活动单元格
                    if (dataGridView.SelectedRows.Count == 1)
                    {
                        dataGridView.CurrentCell = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex];
                    }

                    contextMenuStrip.Show(MousePosition.X, MousePosition.Y);
                }*/
            }
        }

        private void toolStripButtonShowList_Click(object sender, EventArgs e)
        {
     

        }

        private void toolStripMenuItemDeleteOne_Click(object sender, EventArgs e)
        {
            deleteSelectedItem();
        }

        private void toolStripMenuItemDeleteAll_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("请确认是否删除当前所有记录", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
            {

                for (int i = 0; i < this.dataGridView.Rows.Count; i++)
                {
                    object tag = this.dataGridView.Rows[i].Tag;
                    if (tag != null)
                    {
                        this.dataGridView.Rows[i].Selected = true;
                    }

                }
                deleteSelectedItem();
            }
        }

        private void toolStripFinishButton_Click(object sender, EventArgs e)
        {
            finishExperiment();

        }


        private void ToolStripMenuItemFinish_Click(object sender, EventArgs e)
        {
            finishExperiment();
        }

        private void ToolStripMenuItemExit_Click(object sender, EventArgs e)
        {

            if (this.ExperimentIsRunning)
            {
                finishExperiment();
            }
            Application.Exit();
        }

        private void MainFrm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.ExperimentIsRunning)
            {
                finishExperiment();
            }
            Application.Exit();
        }


#endregion

#region 过时代码

        /*
       private ChartDataInfo caculateChartData(ArrayList list, ArrayList hDataList,ArrayList pDataList,ArrayList eDataList, Double[] paramH,Double[] paramP,Double[] paramE)
       {
           int xUnitCount = 10;
           int yUnitCount = 5;
           double axisMaxRate = 0.8f;
           int drawPointCount = 30;
           ChartDataInfo chartDataInfo = new ChartDataInfo();

           //获取最小流量和最大流量
           double maxQ = 0.0f;
           double minQ = Double.MaxValue;

           //获取扬程的最大值和最小值
           Double maxHY = 0.0f;
           Double minHY = Double.MaxValue;

           //获取Y轴数据的最大值和最小值
           Double maxPY = 0.0f;
           Double minPY = Double.MaxValue;

           Double maxEY = 0.0f;
           Double minEY = Double.MaxValue;

           List<Double[]> hPointList = new List<double[]>();
           List<Double[]> pPointList = new List<double[]>();
           List<Double[]> ePointList = new List<double[]>();

           for (int i = 0; i < list.Count; i++)
           {
               PumpAlgorithm.Data d = (PumpAlgorithm.Data)list[i];
               //流量最大值和最小值
               double delta = d.Liuliang - maxQ;
               if (delta >= 0.0001)
               {
                   maxQ = d.Liuliang;
               }
               delta = d.Liuliang - minQ;
               if (delta <= -0.0001)
               {
                   minQ = d.Liuliang;
               }

               //扬程最大值和最小值
               Double hy = (Double)hDataList[i];
               delta = hy - maxHY;
               if (delta >= 0.0001)
               {
                   maxHY = hy;
               }
               delta = hy - minHY;
               if (delta <= -0.0001)
               {
                   minHY = hy;
               }

               //功率最大最小值
               Double py = (Double)pDataList[i];
               delta = py - maxPY;
               if (delta >= 0.0001)
               {
                   maxPY = py;
               }
               delta = py - minPY;
               if (delta <= -0.0001)
               {
                   minPY = py;
               }

               //效率最大最小值
               Double ey = (Double)eDataList[i];
               delta = ey - maxEY;
               if (delta >= 0.0001)
               {
                   maxEY = ey;
               }
               delta = ey - minEY;
               if (delta <= -0.0001)
               {
                   minEY = ey;
               }
               hPointList.Add(new double[] { d.Liuliang, hy });
               pPointList.Add(new double[] { d.Liuliang, py });
               ePointList.Add(new double[] { d.Liuliang, ey });
           }


           //求出最大值，并且做一个坐标余量的计算。
           Double maxXQAxis =  maxQ / axisMaxRate;
           Double maxHYAxis =  maxHY / axisMaxRate;
           Double maxPYAxis =  maxPY / axisMaxRate;
           Double maxEYAxis =  maxEY / axisMaxRate;

           //根据功率和效率的最大值，求出功率和效率在坐标上的比率（功率效率曲线展示在一条Y轴上）
           Double peRate = maxPYAxis / maxEYAxis;

           double xQDoubleUnit = maxXQAxis / xUnitCount;
           double yPDoubleUnit = maxPYAxis / yUnitCount;
           double yHDoubleUnit = maxHYAxis / yUnitCount;
           if (xQDoubleUnit - 1.0 > 0.001)
           {
               xQDoubleUnit = (Double)(int)xQDoubleUnit;
           }
           else
           {
               xQDoubleUnit = (Double)(int)(xQDoubleUnit * 100) / 100.0f;
           }

           if (yHDoubleUnit - 1.0 > 0.001)
           {
               yHDoubleUnit = (Double)(int)yHDoubleUnit;
           }
           else
           {
               yHDoubleUnit = (Double)(int)(yHDoubleUnit * 100) / 100.0f;
           }

           if (yPDoubleUnit - 1.0 > 0.001)
           {
               yPDoubleUnit = (Double)(int)yPDoubleUnit;
           }
           else
           {
               yPDoubleUnit = (Double)(int)(yPDoubleUnit * 100) / 100.0f;
           }

           //设置报表设置的参数
           chartDataInfo.MinXQAxis = 0.0f;
           chartDataInfo.MaxXQAxis = maxXQAxis;
           chartDataInfo.MinYHAxis = 0.0f;
           chartDataInfo.MaxYHAxis = maxHYAxis;
           chartDataInfo.MinYPAxis = 0.0f;
           chartDataInfo.MaxYPAxis = maxPYAxis;
           chartDataInfo.AxisXQInterval = xQDoubleUnit;
           chartDataInfo.AxisYHInterval = yHDoubleUnit;
           chartDataInfo.AxisYPInterval = yPDoubleUnit;
           chartDataInfo.PeRate = peRate;
           chartDataInfo.XUnitCount = xUnitCount;
           chartDataInfo.YUnitCount = yUnitCount;


           //根据公式，平均选取30个点，用于报表中画曲线的点
           Double[] xValue = new Double[drawPointCount + 1];
           Double[] yhValue = new Double[drawPointCount + 1];
           Double[] ypValue = new Double[drawPointCount + 1];
           Double[] yeValue = new Double[drawPointCount + 1];
           double dd = (maxQ - minQ) / drawPointCount;
           for (int i = 0; i <= drawPointCount; i++)
           {
               xValue[i] = minQ + i * dd;
               Double q = xValue[i];
               yhValue[i] = CanonicalAlgorithm.caculateValue(q, paramH);
               ypValue[i] = CanonicalAlgorithm.caculateValue(q, paramP);
               yeValue[i] = peRate * CanonicalAlgorithm.caculateValue(q, paramE);
               //hpValue[i] = param[0] * Math.Pow(q, 4) + param[1] * Math.Pow(q, 3) + param[2] * Math.Pow(q, 2) + param[3] * Math.Pow(q, 1) + param[4] * Math.Pow(q, 0);
               //ypValue[i] = param[0] * Math.Pow(q, 4) + param[1] * Math.Pow(q, 3) + param[2] * Math.Pow(q, 2) + param[3] * Math.Pow(q, 1) + param[4] * Math.Pow(q, 0);

               //按比例缩放
               //yeValue[i] = peRate * (param[0] * Math.Pow(q, 4) + param[1] * Math.Pow(q, 3) + param[2] * Math.Pow(q, 2) + param[3] * Math.Pow(q, 1) + param[4] * Math.Pow(q, 0));

           }
           chartDataInfo.DrawXQList = new ArrayList(xValue);
           chartDataInfo.DrawYHList = new ArrayList(yhValue);
           chartDataInfo.DrawYPList = new ArrayList(ypValue);
           chartDataInfo.DrawYEList = new ArrayList(yeValue);

           chartDataInfo.InputQHPoints = hPointList;
           chartDataInfo.InputQPPoints = pPointList;
           chartDataInfo.InputQEPoints = ePointList;


           return chartDataInfo;
       }
         */


        /*
     private void readPLC()
     {

         float presureIn =    plc.readVData(100);
         float presureOut =   plc.readVData(110);
         float flow =         plc.readVData(210); //plc.readVData(experiment.FlowmeterAddress);
         float temperature =  plc.readVData(180);
         float speed =        plc.readVData(190);

         textBoxJKYL.Invoke(new Action(() => { this.textBoxJKYL.Text = presureIn.ToString(); }));
         textBoxCKYL.Invoke(new Action(() => {
             this.textBoxCKYL.Text = presureOut.ToString();
         }));
         textBoxTHLL.Invoke(new Action(() => {
             this.textBoxTHLL.Text = flow.ToString();
         }));
         textBoxWD.Invoke(new Action(() => {
             this.textBoxWD.Text = temperature.ToString();
         }));
         textBoxDJZS.Invoke(new Action(() => {
             this.textBoxDJZS.Text = speed.ToString();
         }));

         ushort[] meanData = modBus.ReadHoldingRegisters(1, 544, 20);
         float dianya =  getValue(meanData[0], meanData[1]);
         float dianliu = getValue(meanData[2], meanData[3]);
         float yggl =  getValue(meanData[4], meanData[5]);
         float wggl =  getValue(meanData[6], meanData[7]);
         float szgl =  getValue(meanData[8], meanData[9]);
         float glys =  getValue(meanData[10], meanData[11]);
         textBoxDL.Invoke(new Action(() => {
             this.textBoxDL.Text = dianliu.ToString();
         }));
         textBoxDY.Invoke(new Action(() => {
             this.textBoxDY.Text = dianya.ToString();
         }));
         textBoxYGGL.Invoke(new Action(() => {
             this.textBoxYGGL.Text = yggl.ToString();
         }));

     }
     */


        /*
        class ChartData:ICloneable
        {
            double maxXAxis;
            double minXAxis;
            double maxYAxis;
            int xUnitCount;
            int yUnitCount;
            double axisXInterval;
            double axisYInterval;
            ArrayList drawXList;
            ArrayList drawYList;
            Boolean hasRate=false;
            Double rate=1;
            List<Double[]> inputPoints = new List<double[]>();
            /// <summary>
            /// X轴最大值
            /// </summary>
            public double MaxXAxis { get => maxXAxis; set => maxXAxis = value; }
            /// <summary>
            /// X轴最小值
            /// </summary>
            public double MinXAxis { get => minXAxis; set => minXAxis = value; }
            /// <summary>
            /// Y轴最大值
            /// </summary>
            public double MaxYAxis { get => maxYAxis; set => maxYAxis = value; }
            /// <summary>
            /// Y轴最大值
            /// </summary>
            public double MinYAxis { get; set; }
            /// <summary>
            /// X轴等分数         
            /// </summary>
            public int XUnitCount { get => xUnitCount; set => xUnitCount = value; }
            /// <summary>
            /// Y轴等分数         
            /// </summary>
            public int YUnitCount { get => yUnitCount; set => yUnitCount = value; }
            /// <summary>
            /// X轴每等份的长度       
            /// </summary>
            public double AxisXInterval { get => axisXInterval; set => axisXInterval = value; }
            /// <summary>
            /// Y 轴每等份的长度       
            /// </summary>
            public double AxisYInterval { get => axisYInterval; set => axisYInterval = value; }
            /// <summary>
            /// 画曲线所需要的点X的集合      
            /// </summary>
            public ArrayList DrawXList { get => drawXList; set => drawXList = value; }
            /// <summary>
            /// 画曲线所需要的点Y的集合      
            /// </summary>
            public ArrayList DrawYList { get => drawYList; set => drawYList = value; }
            /// <summary>
            /// 画图所需要的输入值    
            /// </summary>
            public List<double[]> InputPoints { get => inputPoints; set => inputPoints = value; }
            public bool HasRate { get => hasRate; set => hasRate = value; }
            public double Rate { get => rate; set => rate = value; }

            public object Clone()
            {
                return MemberwiseClone();
            }
        }

        /// <summary>
        /// 计算报表展示所需要的数据
        /// </summary>
        /// <param name="list">包含了获取到的流量值</param>
        /// <param name="yDataList">测量或者根据测量计算出来的（扬程，功率，效率）值</param>
        /// <param name="param">流量和其他值之间的换算参数</param>
        /// <returns></returns>
        private ChartData caculateChartDataByParams(ArrayList list, ArrayList yDataList, Double[] param)
        {
            int xUnitCount = 10;
            int yUnitCount = 5;
            double axisMaxRate = 0.8f;
            int drawPointCount = 30;
            ChartData chartData = new ChartData();

            //获取最小流量和最大流量
            double maxQ = 0.0f;
            double minQ = Double.MaxValue;
            //获取Y轴数据的最大值和最小值
            Double maxY = 0.0f;
            Double minY = Double.MaxValue;

            for (int i = 0; i < list.Count; i++)
            {
                PumpAlgorithm.Data d = (PumpAlgorithm.Data)list[i];
                double delta = d.Liuliang - maxQ;
                if (delta >= 0.0001)
                {
                    maxQ = d.Liuliang;
                }
                delta = d.Liuliang - minQ;
                if (delta <= -0.0001)
                {
                    minQ = d.Liuliang;
                }

                Double y = (Double)yDataList[i];
                delta = y - maxY;
                if (delta >= 0.0001)
                {
                    maxY = y;
                }
                delta = y - minY;
                if (delta <= -0.0001)
                {
                    minY = y;
                }
                chartData.InputPoints.Add(new double[] { d.Liuliang, y });
            }


            
            Double maxXAxis = maxQ / axisMaxRate;
            Double maxYAxis = maxY / axisMaxRate;

            double xDoubleUnit = maxXAxis / xUnitCount;
            double yDoubleUnit = maxYAxis / yUnitCount;
            if (xDoubleUnit - 1.0 > 0.001)
            {
                xDoubleUnit = (Double)(int)xDoubleUnit;
            }
            else
            {
                xDoubleUnit = (Double)(int)(xDoubleUnit * 100) / 100.0f;
            }

            if (yDoubleUnit - 1.0 > 0.001)
            {
                yDoubleUnit = (Double)(int)yDoubleUnit;
            }
            else
            {
                yDoubleUnit = (Double)(int)(yDoubleUnit * 100) / 100.0f;
            }

            //设置报表设置的参数

            chartData.MinXAxis = 0.0f;
            chartData.MinYAxis = 0.0f;
            chartData.MaxXAxis = maxXAxis;
            chartData.MaxYAxis = maxYAxis;
            chartData.AxisXInterval = xDoubleUnit;
            chartData.AxisYInterval = yDoubleUnit;
            chartData.XUnitCount = xUnitCount;
            chartData.YUnitCount = yUnitCount;

            //根据公式，平均选取30个点，用于报表中画曲线的点
            Double[] xValue = new Double[drawPointCount+1];
            Double[] yValue = new Double[drawPointCount+1];
            double dd = (maxQ - minQ) / drawPointCount;
            for (int i = 0; i <= drawPointCount; i++)
            {
                xValue[i] = minQ + i * dd;
                Double q = xValue[i];
                yValue[i] = param[0] * Math.Pow(q, 4) + param[1] * Math.Pow(q, 3) + param[2] * Math.Pow(q, 2) + param[3] * Math.Pow(q, 1) + param[4] * Math.Pow(q, 0);
               

            }
            chartData.DrawXList = new ArrayList(xValue);
            chartData.DrawYList = new ArrayList(yValue);

            return chartData;
        }

        private void DrawChart(String chartAreaName, String splineSeriesName, String pointSeriesName, ChartData chartData,Boolean bandingAxis2)
        {
            Axis axisX = this.chart.ChartAreas[chartAreaName].AxisX;
            Axis axisY = this.chart.ChartAreas[chartAreaName].AxisY;
            if (bandingAxis2)
            {
                axisX = this.chart.ChartAreas[chartAreaName].AxisX2;
                axisY = this.chart.ChartAreas[chartAreaName].AxisY2;
            }


            axisX.Maximum = chartData.MaxXAxis;
            axisX.Minimum = chartData.MinXAxis;
            axisY.Maximum = chartData.MaxYAxis;
            axisY.Minimum = chartData.MinYAxis;

            axisX.Interval = chartData.AxisXInterval;
            axisY.Interval = chartData.AxisYInterval;

            //chart.Series.Add("QH");
            chart.Series[splineSeriesName].Points.DataBindXY(chartData.DrawXList, chartData.DrawYList);

            //画出测量的点
            foreach(Double[] d in chartData.InputPoints)
            {
                chart.Series[pointSeriesName].Points.Add(new DataPoint(d[0], d[1]));
            }
            
        }

        */
#endregion


    }
}
